﻿namespace OboutInc.TextMenu
{
    using OboutInc.TextMenu.Designer;
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Drawing;
    using System.Drawing.Design;
    using System.IO;
    using System.Text;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.Design;

    [ParseChildren(true, "Items"), Designer(typeof(TextMenuDesigner), typeof(IDesigner)), ToolboxBitmap(typeof(OboutInc.TextMenu.TextMenu), "icon.bmp"), PersistChildren(false)]
    public class TextMenu : Control, INamingContainer
    {
        private ArrayList _allItemsIds;
        private ItemsCollection _items;
        private ArrayList _itemsOrder;
        private Hashtable _menuItems;
        private ArrayList _parentItems;
        private bool DesignMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
        private string script_version = (Constants.version_year.ToString() + Constants.version_month.ToString().PadLeft(2, '0'));

        public void Add(string parentId, string id, string innerHtml)
        {
            if ((id == null) || (id == string.Empty))
            {
                throw new Exception("Obout TextMenu AddItem: ID is not set.");
            }
            this.AddItem(new Item(parentId, id, innerHtml));
        }

        public void Add(string parentId, string id, string innerHtml, string url)
        {
            if ((id == null) || (id == string.Empty))
            {
                throw new Exception("Obout TextMenu AddItem: ID is not set.");
            }
            string relativeUrl = url;
            if (((relativeUrl != null) && (relativeUrl.Length > 0)) && (relativeUrl.IndexOf("~") == 0))
            {
                relativeUrl = base.ResolveUrl(relativeUrl);
            }
            this.AddItem(new Item(parentId, id, innerHtml, relativeUrl));
        }

        public void Add(string parentId, string id, string innerHtml, string url, string urlTarget)
        {
            if ((id == null) || (id == string.Empty))
            {
                throw new Exception("Obout TextMenu AddItem: ID is not set.");
            }
            string relativeUrl = url;
            if (((relativeUrl != null) && (relativeUrl.Length > 0)) && (relativeUrl.IndexOf("~") == 0))
            {
                relativeUrl = base.ResolveUrl(relativeUrl);
            }
            this.AddItem(new Item(parentId, id, innerHtml, relativeUrl, urlTarget));
        }

        private void AddItem(Item mi)
        {
            if (this.AllItemsIds.Contains(mi.ID))
            {
                throw new Exception("Duplicate Item's ID: '" + mi.ID + "'");
            }
            this.AllItemsIds.Add(mi.ID);
            if ((mi.ParentID == null) || (mi.ParentID == string.Empty))
            {
                this.ParentMenuItems.Add(mi);
            }
            else
            {
                if (this.MenuItems[mi.ParentID] == null)
                {
                    this.ItemsOrder.Add(mi.ParentID);
                    this.MenuItems[mi.ParentID] = new ArrayList();
                }
                ((ArrayList) this.MenuItems[mi.ParentID]).Add(mi);
            }
        }

        private string ArrangePath(string prefix, string file)
        {
            string relativeUrl = Path.Combine(prefix, file).Replace(@"\", "/");
            return base.ResolveUrl(relativeUrl);
        }

        protected override void CreateChildControls()
        {
            foreach (Item item in this.Items)
            {
                this.Add(item.ParentID, item.ID, item.InnerHtml, item.Url, item.UrlTarget);
            }
            base.CreateChildControls();
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            this.Page.Session["ob_tm_commonRendered"] = false;
        }

        private void Page_Unload(object sender, EventArgs e)
        {
            this.Page.Session["ob_tm_commonRendered"] = null;
        }

        protected override void Render(HtmlTextWriter writer)
        {
            try
            {
                this.Page.Response.CacheControl = "no-cache";
                this.Page.Response.AddHeader("Pragma", "no-cache");
                this.Page.Response.Expires = -1;
                this.Page.Response.Cache.SetAllowResponseInBrowserHistory(false);
                this.Page.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            }
            catch
            {
            }
            writer.WriteLine("<div style=\"height:100%;\">");
            if (!((bool) this.Page.Session["ob_tm_commonRendered"]))
            {
                this.Page.Unload += new EventHandler(this.Page_Unload);
                writer.Write("<span style=\"display:none\">&nbsp;</span>");
                if (this.StyleFolder != string.Empty)
                {
                    if (this.StyleFileName != string.Empty)
                    {
                        writer.WriteLine("<link rel=\"stylesheet\" type=\"text/css\" href=\"" + this.ArrangePath(this.StyleFolder, this.StyleFileName) + "\" />");
                    }
                }
                else
                {
                    writer.WriteLine("<link rel=\"stylesheet\" type=\"text/css\" href=\"" + this.Page.ClientScript.GetWebResourceUrl(base.GetType(), "OboutInc.TextMenu.Resources.style.css") + "\" />");
                }
                string webResourceUrl = this.Page.ClientScript.GetWebResourceUrl(base.GetType(), "OboutInc.TextMenu.Resources.script.min.js");
                if (new ScriptManagerHelper(this).IsAjax && this.Page.IsCallback)
                {
                    new ScriptManagerHelper(this).RegisterClientScriptInclude(this, "mainScript", webResourceUrl);
                }
                else
                {
                    writer.WriteLine("<script language=\"JavaScript\" src=\"" + webResourceUrl + "\"></script>");
                }
                this.Page.Session["ob_tm_commonRendered"] = true;
            }
            StringBuilder builder = new StringBuilder();
            StringBuilder builder2 = new StringBuilder();
            string str3 = (this.RightToLeft ? "direction: rtl;text-align: right;" : "") + ((this.ColorBackground.Length > 0) ? ("background-color:" + this.ColorBackground + ";") : "") + ((this.ColorFont.Length > 0) ? ("color:" + this.ColorFont + ";") : "") + ((this.FontParent.Length > 0) ? ("font:" + this.FontParent + ";") : "") + (this.Vertical ? ("text-align:" + (this.RightToLeft ? "right" : "left") + ";") : "");
            string text1 = ((this.ColorFont.Length > 0) ? ("color:" + this.ColorFont + ";") : "") + ((this.FontParent.Length > 0) ? ("font:" + this.FontParent + ";") : "");
            string text2 = (this.RightToLeft ? "direction: rtl;" : "") + ((this.ColorBackground.Length > 0) ? ("background-color:" + this.ColorBackground + ";") : "") + ((this.ColorFont.Length > 0) ? ("color:" + this.ColorFont + ";") : "") + ((this.Font.Length > 0) ? ("font:" + this.Font + ";") : "");
            writer.Write("<div><table width=\"0\" height=\"0\" class=\"parentMenuContainer\" style=\"position:relative;left:0px;top:0px;\"><tbody><tr>");
            int num = 0;
            foreach (Item item in this.ParentMenuItems)
            {
                builder2 = new StringBuilder();
                bool flag = false;
                for (int i = 0; i < this.ItemsOrder.Count; i++)
                {
                    if (this.ItemsOrder[i].ToString() == item.ID)
                    {
                        builder2.Append(((builder2.Length > 0) ? "," : "") + "['" + this.ID + "_" + i.ToString() + "','" + this.ItemsOrder[i].ToString() + "']");
                        flag = true;
                    }
                }
                writer.Write(string.Concat(new object[] { 
                    "<td><table class=\"parentMenuItem\" onmouseover=\"TM_InitSingleStartElem(event, this, '", item.ID, "', '", this.ID, "', [", builder2, "])\" id=\"tm_", item.ID, "\" style=\"", str3, "\"><tbody><tr><td unselectable=\"on\" colspan=\"2\" id=\"tm_contentCell\" style=\"", str3, "\">", (item.Url.Length > 0) ? ("<a href=\"" + item.Url + "\"" + ((item.UrlTarget.Length > 0) ? (" target=\"" + item.UrlTarget + "\"") : "") + "style=\"" + str3 + "\">") : "", item.InnerHtml, (item.Url.Length > 0) ? "</a>" : "", 
                    "</td>"
                 }));
                if (flag)
                {
                    writer.Write("<td unselectable=\"on\" id=\"tm_submenuCell\" nowrap=\"true\">");
                    writer.Write(this.SubMenuText);
                    writer.Write("</td>");
                }
                writer.Write("</tr></tbody></table></td>");
                if (this.Vertical && ((num + 1) < this.ParentMenuItems.Count))
                {
                    writer.Write("</tr><tr>");
                }
                builder.Append(((builder.Length > 0) ? "," : "") + "[\"" + item.ID + "\",\"" + this.ID + "\"]");
                num++;
            }
            writer.Write("</tr></tbody></table></div>");
            for (num = 0; num < this.ItemsOrder.Count; num++)
            {
                string str4 = "";
                if (this.Page.Request.UserAgent != null)
                {
                    str4 = this.Page.Request.UserAgent.ToLower();
                }
                if ((str4.IndexOf("msie") != -1) && (str4.IndexOf("opera") == -1))
                {
                    writer.Write("<iframe id=\"tm_Menu_" + this.ID + "_" + num.ToString() + "__iframe\" src=\"javascript:false;\" frameBorder=\"0\" class=\"menuContainerIframeUnderlay\" style=\"display:none;\"></iframe>");
                }
                writer.Write("<div id=\"tm_Menu_" + this.ID + "_" + num.ToString() + "__underlay\" class=\"menuContainerIframeUnderlay\" style=\"display:none;\"></div>");
                writer.Write("<div class=\"menuContainerDiv\" id=\"tm_Menu_" + this.ID + "_" + num.ToString() + "\">");
                writer.Write("<table class=\"menuContainer\"><tbody>");
                foreach (Item item2 in (ArrayList) this.MenuItems[this.ItemsOrder[num].ToString()])
                {
                    writer.Write("<tr><td unselectable=\"on\">");
                    writer.Write("<table class=\"menuItem\" id=\"tm_" + item2.ID + "\"" + (this.RightToLeft ? "style=\"direction: rtl;\"" : "") + "><tbody><tr><td colspan=\"2\" unselectable=\"on\" id=\"tm_contentCell\">" + ((item2.Url.Length > 0) ? ("<a href=\"" + item2.Url + "\"" + ((item2.UrlTarget.Length > 0) ? (" target=\"" + item2.UrlTarget + "\"") : "") + ">") : "") + item2.InnerHtml + "</a></td></tr></tbody></table>");
                    writer.Write("</td></tr>");
                }
                writer.Write("</tbody></table>");
                writer.Write("</div>");
                builder2.Append(((builder2.Length > 0) ? "," : "") + "[\"" + this.ID + "_" + num.ToString() + "\",\"" + this.ItemsOrder[num].ToString() + "\"]");
            }
            if (!new ScriptManagerHelper(this).IsAjax)
            {
                writer.Write("<script language=\"javascript\">");
                StringWriter writer2 = new StringWriter();
                HtmlTextWriter writer3 = new HtmlTextWriter(writer2);
                writer3.Write("window.tm_" + this.ID + "_StyleFolder=\"" + this.StyleFolder + ((!this.StyleFolder.EndsWith("/") && (this.StyleFolder.Length > 0)) ? "/" : "") + "\";");
                writer3.Write("window.tm_" + this.ID + "_AlignMode=\"" + (this.Vertical ? "vertical" : "horizontal") + "\";");
                writer3.Write("window.tm_" + this.ID + "_menuCssStyles=[\"" + this.ColorBackground.ToString().Replace("\"", "\\\"") + "\",\"" + this.ColorFont.ToString().Replace("\"", "\\\"") + "\",\"" + this.Font.ToString().Replace("\"", "\\\"") + "\",\"" + this.FontParent.ToString().Replace("\"", "\\\"") + "\",\"" + this.ColorBackgroundOver.ToString().Replace("\"", "\\\"") + "\",\"" + this.ColorFontOver.ToString().Replace("\"", "\\\"") + "\"];");
                writer3.Write("window.tm_" + this.ID + "_AutoPosition=" + this.AutoPosition.ToString().ToLower() + ";");
                writer3.Write("window.tm_" + this.ID + "_RightToLeft=" + this.RightToLeft.ToString().ToLower() + ";");
                writer3.Write("window.tm_" + this.ID + "_SubMenuText=\"" + this.SubMenuText.Replace("\"", "\\\"") + "\";");
                writer3.Write("window.tm_" + this.ID + "_PersistHoveredItem=" + this.PersistHoveredItem.ToString().ToLower() + ";");
                writer3.Write(string.Concat(new object[] { "var TM_menusRel_", this.ID, " = [", builder2, "];" }));
                writer3.Write("TM_InitMenu()");
                writer3.Flush();
                writer.Write(writer2.GetStringBuilder().ToString());
                writer.Write("</script>");
            }
            else
            {
                StringBuilder builder3 = new StringBuilder();
                StringWriter writer4 = new StringWriter();
                HtmlTextWriter writer5 = new HtmlTextWriter(writer4);
                writer5.Write("window.tm_" + this.ID + "_StyleFolder=\"" + this.StyleFolder + ((!this.StyleFolder.EndsWith("/") && (this.StyleFolder.Length > 0)) ? "/" : "") + "\";");
                writer5.Write("window.tm_" + this.ID + "_AlignMode=\"" + (this.Vertical ? "vertical" : "horizontal") + "\";");
                writer5.Write("window.tm_" + this.ID + "_menuCssStyles=[\"" + this.ColorBackground.ToString().Replace("\"", "\\\"") + "\",\"" + this.ColorFont.ToString().Replace("\"", "\\\"") + "\",\"" + this.Font.ToString().Replace("\"", "\\\"") + "\",\"" + this.FontParent.ToString().Replace("\"", "\\\"") + "\",\"" + this.ColorBackgroundOver.ToString().Replace("\"", "\\\"") + "\",\"" + this.ColorFontOver.ToString().Replace("\"", "\\\"") + "\"];");
                writer5.Write("window.tm_" + this.ID + "_AutoPosition=" + this.AutoPosition.ToString().ToLower() + ";");
                writer5.Write("window.tm_" + this.ID + "_RightToLeft=" + this.RightToLeft.ToString().ToLower() + ";");
                writer5.Write("window.tm_" + this.ID + "_SubMenuText=\"" + this.SubMenuText.Replace("\"", "\\\"") + "\";");
                writer5.Write("window.tm_" + this.ID + "_PersistHoveredItem=" + this.PersistHoveredItem.ToString().ToLower() + ";");
                writer5.Write(string.Concat(new object[] { "var TM_menusRel_", this.ID, " = [", builder2, "];" }));
                writer5.Write("TM_InitMenu();\n");
                writer5.Flush();
                builder3.Append(writer4.GetStringBuilder().ToString());
                new ScriptManagerHelper(this).RegisterStartupScript(this, "TMScript" + this.ID, builder3.ToString(), true);
            }
            writer.WriteLine();
            writer.WriteLine();
            writer.WriteLine("<!--   obout_textmenu version " + this.ComponentVersion + "   http://www.obout.com   -->");
            writer.WriteLine();
            writer.WriteLine();
            writer.WriteLine("</div>");
        }

        private ArrayList AllItemsIds
        {
            get
            {
                if (this._allItemsIds == null)
                {
                    this._allItemsIds = new ArrayList();
                }
                return this._allItemsIds;
            }
        }

        [Description("If TextMenu should AutoPosition if it would be shown outside of screen."), Bindable(true), Category("Styles"), DefaultValue(true)]
        public bool AutoPosition
        {
            get
            {
                object obj2 = this.ViewState["AutoPosition"];
                if (obj2 == null)
                {
                    this.ViewState["AutoPosition"] = true;
                    return true;
                }
                return (bool) obj2;
            }
            set
            {
                this.ViewState["AutoPosition"] = value;
            }
        }

        [Description("Background Color for Menu Items."), Category("Styles"), DefaultValue("#586F9B"), Bindable(true)]
        public string ColorBackground
        {
            get
            {
                object obj2 = this.ViewState["ColorBackground"];
                if (obj2 != null)
                {
                    return (string) obj2;
                }
                return "#586F9B";
            }
            set
            {
                this.ViewState["ColorBackground"] = value;
            }
        }

        [Description("Background Color for Menu Items when mouse over."), Category("Styles"), Bindable(true), DefaultValue("#E4E9EF")]
        public string ColorBackgroundOver
        {
            get
            {
                object obj2 = this.ViewState["ColorBackgroundOver"];
                if (obj2 != null)
                {
                    return (string) obj2;
                }
                return "#E4E9EF";
            }
            set
            {
                this.ViewState["ColorBackgroundOver"] = value;
            }
        }

        [Category("Styles"), DefaultValue("#E4E9EF"), Description("Font Color for Menu Items."), Bindable(true)]
        public string ColorFont
        {
            get
            {
                object obj2 = this.ViewState["ColorFont"];
                if (obj2 != null)
                {
                    return (string) obj2;
                }
                return "#E4E9EF";
            }
            set
            {
                this.ViewState["ColorFont"] = value;
            }
        }

        [Description("Font Color for Menu Items when mouse over."), Category("Styles"), DefaultValue("#586F9B"), Bindable(true)]
        public string ColorFontOver
        {
            get
            {
                object obj2 = this.ViewState["ColorFontOver"];
                if (obj2 != null)
                {
                    return (string) obj2;
                }
                return "#586F9B";
            }
            set
            {
                this.ViewState["ColorFontOver"] = value;
            }
        }

        [Browsable(false)]
        public string ComponentVersion
        {
            get
            {
                return ("3." + Constants.version_year.ToString() + "." + Constants.version_month.ToString() + "." + Constants.version_number.ToString());
            }
        }

        [Bindable(true), Category("Styles"), DefaultValue("11px Verdana"), Description("Text Font for Menu Items.")]
        public string Font
        {
            get
            {
                object obj2 = this.ViewState["Font"];
                if (obj2 != null)
                {
                    return (string) obj2;
                }
                return "11px Verdana";
            }
            set
            {
                this.ViewState["Font"] = value;
            }
        }

        [Bindable(true), Category("Styles"), DefaultValue("bold 11px Verdana"), Description("Text Font for Parent Items (optional)")]
        public string FontParent
        {
            get
            {
                object obj2 = this.ViewState["FontParent"];
                if (obj2 != null)
                {
                    return (string) obj2;
                }
                return (((this.Font.ToLower().IndexOf("bold") == -1) ? "bold " : "") + this.Font);
            }
            set
            {
                this.ViewState["FontParent"] = value;
            }
        }

        [Category("Behavior"), NotifyParentProperty(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), PersistenceMode(PersistenceMode.InnerDefaultProperty), Description("TextMenu items collection.")]
        public ItemsCollection Items
        {
            get
            {
                if (this._items == null)
                {
                    this._items = new ItemsCollection();
                }
                return this._items;
            }
        }

        private ArrayList ItemsOrder
        {
            get
            {
                if (this._itemsOrder == null)
                {
                    this._itemsOrder = new ArrayList();
                }
                return this._itemsOrder;
            }
        }

        private Hashtable MenuItems
        {
            get
            {
                if (this._menuItems == null)
                {
                    this._menuItems = new Hashtable();
                }
                return this._menuItems;
            }
        }

        private ArrayList ParentMenuItems
        {
            get
            {
                if (this._parentItems == null)
                {
                    this._parentItems = new ArrayList();
                }
                return this._parentItems;
            }
        }

        [Description("Whether to persist 'hover' style for the item in the main menu after some item in submenu was clicked."), Bindable(true), Category("Behavior"), DefaultValue(false)]
        public bool PersistHoveredItem
        {
            get
            {
                object obj2 = this.ViewState["PersistHoveredItem"];
                if (obj2 == null)
                {
                    this.ViewState["PersistHoveredItem"] = false;
                    return false;
                }
                return (bool) obj2;
            }
            set
            {
                this.ViewState["PersistHoveredItem"] = value;
            }
        }

        [Bindable(true), Description("If TextMenu should display from right to left."), Category("Styles"), DefaultValue(false)]
        public bool RightToLeft
        {
            get
            {
                object obj2 = this.ViewState["RightToLeft"];
                if (obj2 == null)
                {
                    this.ViewState["RightToLeft"] = false;
                    return false;
                }
                return (bool) obj2;
            }
            set
            {
                this.ViewState["RightToLeft"] = value;
            }
        }

        [Bindable(true), Description("CSS file name."), Editor(typeof(UrlEditor), typeof(UITypeEditor)), DefaultValue("style.css"), Category("Appearance")]
        public string StyleFileName
        {
            get
            {
                object obj2 = this.ViewState["StyleFileName"];
                if (obj2 == null)
                {
                    this.ViewState["StyleFileName"] = "style.css";
                    return "style.css";
                }
                return (string) obj2;
            }
            set
            {
                this.ViewState["StyleFileName"] = value;
            }
        }

        [Description("Path to the folder containing the style.css file with menu classes."), DefaultValue(""), Editor(typeof(UrlEditor), typeof(UITypeEditor)), Bindable(true), Category("Appearance")]
        public string StyleFolder
        {
            get
            {
                object obj2 = this.ViewState["StyleFolder"];
                if (obj2 == null)
                {
                    this.ViewState["StyleFolder"] = "";
                    return "";
                }
                return (string) obj2;
            }
            set
            {
                this.ViewState["StyleFolder"] = value;
            }
        }

        [Bindable(true), DefaultValue(">"), Description("Text Font displayed for Menu Items with submenu."), Category("Styles")]
        public string SubMenuText
        {
            get
            {
                object obj2 = this.ViewState["SubMenuText"];
                if (obj2 != null)
                {
                    return (string) obj2;
                }
                return ">";
            }
            set
            {
                this.ViewState["SubMenuText"] = value;
            }
        }

        [Bindable(true), Category("Styles"), DefaultValue(false), Description("If TextMenu's parent items should be aligned vertically.")]
        public bool Vertical
        {
            get
            {
                object obj2 = this.ViewState["Vertical"];
                if (obj2 == null)
                {
                    this.ViewState["Vertical"] = false;
                    return false;
                }
                return (bool) obj2;
            }
            set
            {
                this.ViewState["Vertical"] = value;
            }
        }
    }
}

